package site.jlopen.kuscia.service.job;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.secretflow.v1alpha1.kusciaapi.Job;
import org.secretflow.v1alpha1.kusciaapi.Job.BatchQueryJobStatusRequest;
import org.secretflow.v1alpha1.kusciaapi.Job.BatchQueryJobStatusResponse;
import org.secretflow.v1alpha1.kusciaapi.Job.CreateJobRequest;
import org.secretflow.v1alpha1.kusciaapi.Job.CreateJobResponse;
import org.secretflow.v1alpha1.kusciaapi.Job.DeleteJobRequest;
import org.secretflow.v1alpha1.kusciaapi.Job.DeleteJobResponse;
import org.secretflow.v1alpha1.kusciaapi.Job.JobStatusDetail;
import org.secretflow.v1alpha1.kusciaapi.Job.Party;
import org.secretflow.v1alpha1.kusciaapi.Job.PartyStatus;
import org.secretflow.v1alpha1.kusciaapi.Job.QueryJobRequest;
import org.secretflow.v1alpha1.kusciaapi.Job.QueryJobResponse;
import org.secretflow.v1alpha1.kusciaapi.Job.QueryJobResponseData;
import org.secretflow.v1alpha1.kusciaapi.Job.RestartJobRequest;
import org.secretflow.v1alpha1.kusciaapi.Job.RestartJobResponse;
import org.secretflow.v1alpha1.kusciaapi.Job.StopJobRequest;
import org.secretflow.v1alpha1.kusciaapi.Job.StopJobResponse;
import org.secretflow.v1alpha1.kusciaapi.Job.Task;
import org.secretflow.v1alpha1.kusciaapi.Job.TaskConfig;
import org.secretflow.v1alpha1.kusciaapi.Job.TaskStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import site.jlopen.kuscia.entity.GrpcApiInfo;
import site.jlopen.kuscia.model.job.JobStatusResponeVo;
import site.jlopen.kuscia.model.job.TaskInfo;
import site.jlopen.kuscia.model.job.TaskPartie;
import site.jlopen.kuscia.model.task.TaskStatuPartie;
import site.jlopen.kuscia.model.task.TaskStatusResponeVo;
import site.jlopen.kuscia.properties.KusciaAPIProperties;
import site.jlopen.kuscia.rpc.impl.KusciaJobRpcImpl;

@Service
public class KusciaJobManager extends AbstractJobManager{
	private static Logger logger = LoggerFactory.getLogger(KusciaJobManager.class);

	@Override
	public boolean createJob(GrpcApiInfo apiInfo, String jobId, String initiator, List<TaskInfo> tasks) {
		try {
			KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
			CreateJobRequest.Builder builder = CreateJobRequest.newBuilder()
					.setJobId(jobId)
					.setInitiator(initiator);
			for (TaskInfo taskInfo : tasks) {
				List<Party> parties = new ArrayList<Job.Party>();
				for (TaskPartie partie : taskInfo.getParties()) {
					Party party = Party.newBuilder()
							.setDomainId(partie.getDomainId())
							.setRole(partie.getRole())
							.build();
					parties.add(party);
				}
				Job.Task task = Task.newBuilder()
						.setAppImage(taskInfo.getAppImage())
						.addAllParties(parties)
						.setTaskId(taskInfo.getTask_id())
						.setAlias(taskInfo.getAlias())
						.addAllDependencies(taskInfo.getDependencies())
						.setTaskInputConfig(taskInfo.getTaskInputConfig())
						.setPriority(taskInfo.getPriority())
						.build();
				builder.addTasks(task);
			}
			CreateJobRequest request = builder.build();
			CreateJobResponse response = new KusciaJobRpcImpl(apiProperties).createJob(request);
			logger.info("response:{}", response);
			return true;
		} catch (Exception e) {
			logger.error("创建{}任务失败：{}", jobId, e);
			return false;
		}
	}

	@Override
	public JobStatusResponeVo queryJob(GrpcApiInfo apiInfo, String jobId) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		QueryJobRequest request = QueryJobRequest.newBuilder()
				.setJobId(jobId)
				.build();
		QueryJobResponse response = new KusciaJobRpcImpl(apiProperties).queryJob(request);
		//logger.info("queryJob response:{}", response);
		//logger.info("queryJob data:{}", response.getData());
		//logger.info("queryJob status:{}", response.getStatus());
		QueryJobResponseData data = response.getData();
		String _jobId = data.getJobId();
		String _initiator = data.getInitiator();
		String _state = data.getStatus().getState();
		List <TaskConfig> taskConfigs = data.getTasksList();
		Map<String, String> configMap = new HashMap<String, String>();
		if(null != taskConfigs && taskConfigs.size() > 0) {
			for (TaskConfig task : taskConfigs) {
				configMap.put(task.getTaskId(), task.getTaskInputConfig());
			}
		}
		JobStatusDetail details = data.getStatus();
		logger.info("queryJob details:{}", details);
		List <TaskStatus> tasks = details.getTasksList();
		JobStatusResponeVo vo = new JobStatusResponeVo();
		vo.setJobId(_jobId);
		vo.setInitiator(_initiator);
		vo.setState(_state.toUpperCase());
		
		if(null != tasks && tasks.size() > 0) {
			List<TaskStatusResponeVo> vos = new ArrayList<TaskStatusResponeVo>();
			for (TaskStatus task : tasks) {
				String _taskId = task.getTaskId();
				String _tstate = task.getState();
				String _errMsg = task.getErrMsg();
				vo.addTaskMap(_taskId, _tstate.toUpperCase());
				TaskStatusResponeVo stateVo = new TaskStatusResponeVo(_taskId, _tstate.toUpperCase(), _errMsg, configMap.get(_taskId));
				List <PartyStatus> taskParties = task.getPartiesList();
				if(null != taskParties && taskParties.size() > 0) {
					for (PartyStatus taskPartie : taskParties) {
						String _domainId = taskPartie.getDomainId();
						String _ttstate = taskPartie.getState();
						String _terrMsg = taskPartie.getErrMsg();
						stateVo.addPartie(new TaskStatuPartie(_domainId, _ttstate.toUpperCase(), _terrMsg));
					}
				}
				vos.add(stateVo);
			}
			vo.setTasks(vos);
		}
		return vo;
	}

	@Override
	public void batchQueryJobStatus(GrpcApiInfo apiInfo, List<String> jobIds) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		BatchQueryJobStatusRequest.Builder builder = BatchQueryJobStatusRequest.newBuilder();
		builder.addAllJobIds(jobIds);
		BatchQueryJobStatusRequest request = builder.build();
		BatchQueryJobStatusResponse response = new KusciaJobRpcImpl(apiProperties).batchQueryJobStatus(request);
		logger.info("response:{}", response);
		
	}

	@Override
	public void deleteJob(GrpcApiInfo apiInfo, String jobId) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		DeleteJobRequest request = DeleteJobRequest.newBuilder()
				.setJobId(jobId)
				.build();
		DeleteJobResponse response = new KusciaJobRpcImpl(apiProperties).deleteJob(request);
		logger.info("response:{}", response);
	}

	@Override
	public void stopJob(GrpcApiInfo apiInfo, String jobId) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		StopJobRequest request = StopJobRequest.newBuilder()
				.setJobId(jobId)
				.build();
		StopJobResponse response = new KusciaJobRpcImpl(apiProperties).stopJob(request);
		logger.info("response:{}", response);
	}

	@Override
	public void watchJob(GrpcApiInfo apiInfo) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		
	}

	@Override
	public void approveJob(GrpcApiInfo apiInfo) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		
	}

	/*@Override
	public void SuspendJob(GrpcApiInfo apiInfo) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		
	}*/
	
	@Override
	public void restartJob(GrpcApiInfo apiInfo, String jobId) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		RestartJobRequest request = RestartJobRequest.newBuilder()
				.setJobId(jobId)
				.build();
		RestartJobResponse response = new KusciaJobRpcImpl(apiProperties).RestartJob(request);
		logger.info("response:{}", response);
	}
	
	/*@Override
	public void CancelJob(GrpcApiInfo apiInfo) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		
	}*/

}
